﻿using FanucVarProxy.ClientUserControl.Properties;
using Nai.Communication.VarProxy;
using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace FanucVarProxy.ClientUserControl
{
    public partial class FRVarProxyUserControl : UserControl
    {
        public FRVarProxyUserControl()
        {
            InitializeComponent();
        }

        private void Say(string msg)
        {
            Debug.WriteLine(msg);
            //MessageBox.Show(msg);

            Action logToTextbox = new Action(() => this.textBox_msg.Text = msg);
            if (this.InvokeRequired)
            {
                this.Invoke(logToTextbox);
            }
            else
            {
                logToTextbox.Invoke();
            }
        } // end of method

        private void FRCVarProxyUserControl_Load(object sender, EventArgs e)
        {
            this.textBox_ip.Text = Settings.Default.RobotIp;
            this.textBox_sysvar.Text = Settings.Default.SystemVarName;

            this.comboBox_vartype.Items.Add(VarType.NumericReg);
            this.comboBox_vartype.Items.Add(VarType.Flag);
            this.comboBox_vartype.Items.Add(VarType.DigitalInput);
            this.comboBox_vartype.Items.Add(VarType.DigitalOutput);
            this.comboBox_vartype.SelectedIndex = 0;

            this.comboBox_action.Items.Add(VarOperation.Read);
            this.comboBox_action.Items.Add(VarOperation.Write);
            this.comboBox_action.SelectedIndex = 0;

            this.comboBox_action_of_var.Items.Add(VarOperation.Read);
            this.comboBox_action_of_var.Items.Add(VarOperation.Write);
            this.comboBox_action_of_var.SelectedIndex = 0;
        }

        private void button_go_reg_io_Click(object sender, EventArgs e)
        {
            string ip = Settings.Default.RobotIp;
            uint index = (uint)this.numericUpDown_index.Value;
            string selectedObj = this.comboBox_vartype.SelectedItem.ToString();
            string selectedOp = this.comboBox_action.SelectedItem.ToString();

            FRVarProxy request = null;
            VarResponse resp;
            string setVal = string.Empty;
            if (selectedOp == VarOperation.Write.ToString())
            {
                if (selectedObj == VarType.DigitalInput.ToString())
                {
                    Say("Digital Input is read only");
                    return;
                }
                else if (selectedObj == VarType.DigitalOutput.ToString())
                {
                    Say("Do not support writing Digital Output for safety reasons");
                    return;
                }
                else if (selectedObj ==  VarType.Flag.ToString())
                {
                    var fmFlag = new FormFlagValue();
                    fmFlag.ShowDialog();
                    setVal = fmFlag.FlagValue;
                    fmFlag.Dispose();
                    request = FRVarProxy.Factory.CreateWriteFlagRequest(ip, index, setVal == "ON" ? true : false);
                    resp = request.GetResponse();
                    Say($"Writing F[{index}] to {setVal} result: {(resp.OperationOk ? "okay" : "failed")}");
                }
                else if (selectedObj == VarType.NumericReg.ToString())
                {
                    var fmReg = new FormNumericRegValue();
                    fmReg.ShowDialog();
                    setVal = fmReg.RegValue.ToString();
                    fmReg.Dispose();
                    request = FRVarProxy.Factory.CreateWriteNumericRegRequest(ip, index, setVal);
                    resp = request.GetResponse();
                    Say($"Writing R[{index}] to {setVal} result: {(resp.OperationOk ? "okay" : "failed")}");
                }
            } // end of write
            else // read
            {
                if (selectedObj == VarType.DigitalInput.ToString())
                {
                    request = FRVarProxy.Factory.CreateReadDigitalInputRequest(ip, index);
                    resp = request.GetResponse();
                    Say($"Reading DI[{index}] result: {(resp.OperationOk ? "okay" : "failed")} -> {resp.VarValue}");
                    //Say($"Reading DI[{index}] {(resp.OperationOk ? "okay" : "failed")} -> {resp.ParseVarValue}");
                }
                else if (selectedObj == VarType.DigitalOutput.ToString())
                {
                    request = FRVarProxy.Factory.CreateReadDigitalOutputRequest(ip, index);
                    resp = request.GetResponse();
                    Say($"Reading DO[{index}] result: {(resp.OperationOk ? "okay" : "failed")} -> {resp.VarValue}");
                }
                else if (selectedObj == VarType.Flag.ToString())
                {
                    request = FRVarProxy.Factory.CreateReadFlagRequest(ip, index);
                    resp = request.GetResponse();
                    Say($"Reading F[{index}] result: {(resp.OperationOk ? "okay" : "failed")} -> {resp.VarValue}");
                }
                else if (selectedObj == VarType.NumericReg.ToString())
                {
                    request = FRVarProxy.Factory.CreateReadNumericRegRequest(ip, index);
                    resp = request.GetResponse();
                    Say($"Reading R[{index}] result: {(resp.OperationOk ? "okay" : "failed")} -> {resp.VarValue}");
                }
            } // end of read


        } // end of method

        private void button_set_ip_Click(object sender, EventArgs e)
        {
            Settings.Default.RobotIp = this.textBox_ip.Text.Trim();
            Settings.Default.Save();
        } // end of method

        private void button_raise_error_Click(object sender, EventArgs e)
        {
            var req = FRVarProxy.Factory.CreateRaiseSystemAlarmRequest(
                Settings.Default.RobotIp, 
                this.textBox_alarm_msg.Text.Trim() // supports ascii text only
            );
            var resp = req.GetResponse(); // call this in new thread in production
            if (resp.OperationOk)
            {
                Say("Error raised, checkout Teach pendant");
            }
            else
            {
                Say("Failed to raise error");
            }
        } // end of method

        private void button_go_var_Click(object sender, EventArgs e)
        {
            string name = this.textBox_sysvar.Text.Trim();
            Settings.Default.SystemVarName = name;
            Settings.Default.Save();
            if (string.IsNullOrEmpty(name)) return;
            Settings.Default.SystemVarName = name;

            FRVarProxy req = null;
            VarResponse resp;
            if (this.comboBox_action_of_var.SelectedItem.ToString() == VarOperation.Read.ToString())
            {
                req = FRVarProxy.Factory.CreateReadSystemVarRequest(
                    Settings.Default.RobotIp,
                    name
                );
                resp = req.GetResponse(); // call this in new thread in production
                if (resp.OperationOk)
                {
                    Say($"Reading {name} okay ->\r\n\r\n" +
                        $"unparsed value is {resp.VarValue}\r\n" +
                        $"parsed type is {resp.ParsedValueType}\r\n" +
                        $"parsed value is {resp.ParseVarValue}");
                }
                else
                {
                    Say($"Reading {name} failed");
                }
            } // end of read
            else
            {
                var fm = new FormSysVarValue();
                fm.ShowDialog();
                var type_ = fm.VarValueType;
                var value_ = fm.VarValue;
                fm.Dispose();

                if (value_ == null)
                {
                    Say("Invalid value passed in");
                    return;
                }

                if (type_ == typeof(bool))
                {
                    req = FRVarProxy.Factory.CreateWriteSystemVarRequest(
                        Settings.Default.RobotIp, name, (bool)value_
                    );
                }
                else if (type_ == typeof(int))
                {
                    req = FRVarProxy.Factory.CreateWriteSystemVarRequest(
                        Settings.Default.RobotIp, name, (int)value_
                    );
                }
                else if (type_ == typeof(float))
                {
                    req = FRVarProxy.Factory.CreateWriteSystemVarRequest(
                        Settings.Default.RobotIp, name, (float)value_
                    );
                }
                else if (type_ == typeof(string))
                {
                    req = FRVarProxy.Factory.CreateWriteSystemVarRequest(
                        Settings.Default.RobotIp, name, (string)value_
                    );
                }
                if (req == null) return;
                resp = req.GetResponse(); // call this in new thread in production
                Say($"Writing {name} to {value_} result: {(resp.OperationOk ? "okay" : "failed")}");

            }
        } // end of method


    } // end of class


}
